<?php

require_once(FQ_THIRDPARTY.'/dwoo/dwooAutoload.php');

class Flexqueries_base
{
	/**
	 * @var ADOConnection
	 */
	protected $connection;
	

	public function __construct()
	{
		$this->connection = $this->initConnection();
	}
	
	
	/**
	 * @return ADOConnection
	 */
	private function initConnection()
	{
		$c = NewADOConnection(DB_TYPE);
		@$res = $c->Connect(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME);
		
		if(!$res)
			throw new Exception("Unable to connect to the database !");
		
		return $c;
	}
	
	/**
	 * 
	 * @param ADORecordSet $rs
	 * @param bool $encodeBase64
	 */
	protected function rsToXml($rs)
	{
		
		$doc = new DOMDocument("1.0", "UTF-8");
		$tableEl = $doc->createElement('table');
		$rowsEl = $doc->createElement('rows');
		$doc->appendChild($tableEl);
		$tableEl->appendChild($rowsEl);
		$colsEl = null;
		while(!$rs->EOF)
		{
			if(!$colsEl)
			{
				//Construction de l'�l�ment columns
				$colsEl = $doc->createElement('columns');
				$tableEl->appendChild($colsEl);
				//print_r($rs);
				foreach($rs->fields as $key => $val)
				{
					if(is_numeric($key))
						continue;
						
					$colEl = $doc->createElement('column');
					
					$colEl->setAttribute('name', strtoupper($key));
					$colsEl->appendChild($colEl);
				}
			}
			
			$rowEl = $doc->createElement('row');
			$rowsEl->appendChild($rowEl);
			foreach($rs->fields as $key => $val)
			{
				if(is_numeric($key))
					continue;
				
				//encodage de la sortie
				$val = base64_encode($val);
					
				$fieldEl = $doc->createElement(strtoupper($key), $val);
				$rowEl->appendChild($fieldEl);
			}
			
			$rs->MoveNext();
		}
		
		return $doc;
		
	}
	
	/**
	 * Transforms a Recordset into a value object array
	 * 
	 * @param ADORecordSet $rs
	 * @param bool $encodeBase64
	 */
	protected function rsToVOArray($rs, $objectsAsAssociativeArrays = false)
	{
		$arr = array();
		
		while(!$rs->EOF)
		{
			if($objectsAsAssociativeArrays)
				$vo = array();
			else
				$vo = new stdClass();

			foreach($rs->fields as $key => $val)
			{
				if(is_numeric($key))
					continue;
				$key = strtoupper($key);
				$val = utf8_encode($val);
				
				if($objectsAsAssociativeArrays)
					$vo[$key] = $val;
				else
					$vo->$key = $val;
			}
			
			$arr[] = $vo;
			$rs->MoveNext();
		}
		
		return $arr;
		
	}
	
	public static function answerValue($errorCode, $value)
	{
		$doc = new DOMDocument("1.0", "UTF-8");
		$answerEl = $doc->createElement('answer');
		$doc->appendChild($answerEl);
		
		$errorCode = base64_encode($errorCode);
		$value = base64_encode($value);
		
		$answerEl->appendChild($doc->createElement('errorCode', $errorCode));
		$answerEl->appendChild($doc->createElement('value', $value));
		
		return $doc->saveXML();
	}
	
	public static function answerXml($errorCode, $xmlNode)
	{
		$doc = new DOMDocument("1.0", "UTF-8");
		$answerEl = $doc->createElement('answer');
		$doc->appendChild($answerEl);
		
		$errorCode = base64_encode($errorCode);
		
		$answerEl->appendChild($doc->createElement('errorCode', $errorCode));
		$valueEl = $answerEl->appendChild($doc->createElement('value', $value));
		$valueEl->appendChild($doc->importNode($xmlNode, true));
		$answerEl->appendChild($valueEl);
		
		return $doc->saveXML();
	}
	
	public function getSqlFromQueryName($queryName)
	{
		
		$arr = $this->selectToVOArray("Select * from fq_queries where query_name = ?",
									  array($queryName));
		
		if(empty($arr))
			throw new Exception("Query $queryName not found in table !");

		return $arr[0]->QUERY_TEXT;	
	}
	
	public function getSqlFromFile($sql)
	{
		if(!file_exists(SQL_LIBRARY))
			throw new Exception("SQL library does not exist !");
			
		$doc = new DOMDocument();
		$doc->load(SQL_LIBRARY);
		
		$xpath = new DOMXPath($doc);
		$queries = $xpath->query("//query[@id='$sql']");

		//Returns the first node
		foreach($queries as $query)
			return $query->nodeValue;
		
		throw new Exception("The query '$sql' was not found in the library !");
	}
	
	public function genStandardInsert($table)
	{
		$field_arr = $this->connection->MetaColumnNames($table);
		if(!$field_arr)
			return "Table $table not found";
			
		$fieldList = strtoupper(join(', ', $field_arr));
		$param_arr = array_fill(0, count($field_arr), '?');
		
		$paramList = join(', ', $param_arr);
		
		$insert = "Insert into $table ($fieldList) values ($paramList)";
		
		return $insert;
	}
	
	public function genStandardSelect($table)
	{
		$field_arr = $this->connection->MetaColumnNames($table);
		if(!$field_arr)
			return "Table $table not found";
			
		$fieldList = strtoupper(join(', ', $field_arr));
						
		$select = "Select $fieldList from $table";
		
		return $select;
	}
	
	public function getColumnNames($table)
	{
		$field_arr = $this->connection->MetaColumnNames($table);
		return $field_arr;
	}
	
	public function genStandardUpdate($table)
	{
		$field_arr = $this->connection->MetaColumnNames($table);
		if(!$field_arr)
			return "Table $table not found";
			
		foreach($field_arr as $key => $val)
			$field_arr[$key] = strtoupper($val). " = ?";
		$fieldList = strtoupper(join(', ', $field_arr));
				
		$update = "Update $table set $fieldList where 0 = 1";
		
		return $update;
	}
	
	public function genStandardDelete($table)
	{
		//$field_arr = $this->connection->MetaColumnNames($table);
		//foreach($field_arr as $key => $val)
		//	$field_arr[$key] = strtoupper($val). " = ?";
		//$fieldList = strtoupper(join(', ', $field_arr));

		$delete = "Delete from $table where 0 = 1";
		
		return $delete;
	}
	
	public function getTables()
	{
		$table_arr = $this->connection->MetaTables($table);
		return $table_arr;
	}
		
	protected function debug($header, $message)
	{
		header("$header: $message");
	}
	
	protected function selectToVOArray($sql, $parameters = array(), $objectsAsAssociativeArrays = false)
	{
		$rs = $this->connection->Execute($sql, $parameters);
		if(!$rs)
			throw $this->getSqlException();
			
		$arr = $this->rsToVOArray($rs, $objectsAsAssociativeArrays);
		return $arr;
	}
	
	protected function getSqlException()
	{
		$msg = Flexqueries::answerValue($this->connection->ErrorNo(), $this->connection->ErrorMsg());
		//return new Exception("Exception # ".$this->connection->ErrorNo().": ". $this->connection->ErrorMsg());
		return new Exception($msg);
	}
	
	protected function getSqlErrorMessage()
	{
		return "Exception # ".$this->connection->ErrorNo().": ". $this->connection->ErrorMsg();
	}
}

?>